package com.ehouse;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

public class Drivers {
	private static Drivers instance;
	private final static File root = new File("eHouse");
	private final static File rules = new File(root, "Rules");
	private final static File ids = new File(root, "IDs");
	private final static Object lightsLock = new Object();
	private final static File lights = new File(rules, "lights.txt");
	private final static Object tempLock = new Object();
	private final static File temp = new File(rules, "temperature.txt");
	private final static Object irrigationLock = new Object();
	private final static File irrigation = new File(rules, "irrigation.txt");
	private final static Object andIdLock = new Object();
	private final static File AndregID = new File(ids, "AndroidRegIDs.txt");
//	private final static File AndAuthKey = new File(ids, "AndroidAuthKey.txt");
	private final static Object wpUriLock = new Object();
	private final static File WPUri = new File(ids, "WinPhoneUris.txt");
	
	private static final String AUTH_KEY = "AIzaSyA_tSIEcPuHZkSdAR-zc6x4YiZn8E1v0u0";

	public static Drivers getInstance() {
		if (instance == null)
			try {
				instance = new Drivers();
			} catch (IOException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}

		return instance;
	}

	private Drivers() throws IOException {
		if (!root.exists()) {
			rules.mkdirs();
			ids.mkdir();
			createRuleFiles();
			createIdFiles();
		} else {
			if (!rules.exists()) {
				rules.mkdir();
				createRuleFiles();
			}
			if (!ids.exists()) {
				ids.mkdir();
				createIdFiles();
			}
		}
	}

	private void createRuleFiles() throws IOException {
		lights.createNewFile();
		temp.createNewFile();
		irrigation.createNewFile();
	}

	private void createIdFiles() throws IOException {
		AndregID.createNewFile();
//		AndAuthKey.createNewFile();
		WPUri.createNewFile();
	}

	public void addAndroidRegID(String ID) throws IOException {
		synchronized (andIdLock) {
			List<String> list = getAndroidRegIDs();
			if (list.contains(ID)) {
				return;
			}
			System.out.println("Adding new Android ID: " + ID);
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					AndregID, true)));
			ps.println(ID);
			ps.flush();
			ps.close();
		}
	}

//	public void addAndroidAuthKey(String key) throws IOException {
//		PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
//				AndAuthKey, true)));
//		ps.println(key);
//		ps.flush();
//		ps.close();
//	}

	public void addWindowsPhoneUri(String uri) throws IOException {
		synchronized (wpUriLock) {
			List<String> list = getWinPhoneUris();
			if (list.contains(uri)) {
				return;
			}
			System.out.println("Adding new WP ID: " + uri);
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					WPUri, true)));
			ps.println(uri);
			ps.flush();
			ps.close();
		}
	}

	public List<String> getAndroidRegIDs() throws IOException {
		List<String> regIds = new ArrayList<String>();
		synchronized (andIdLock) {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(AndregID)));
			String line;
			while ((line = br.readLine()) != null) {
				regIds.add(line);
			}
			br.close();
		}
		return regIds;
	}

	public String getAndroidAuthKey() throws IOException {
//		BufferedReader br = new BufferedReader(new InputStreamReader(
//				new FileInputStream(AndAuthKey)));
//		String key = br.readLine();
//		br.close();
		return AUTH_KEY;
	}

	public List<String> getWinPhoneUris() throws IOException {
		List<String> uris = new ArrayList<String>();
		synchronized (wpUriLock) {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(WPUri)));
			String line;
			while ((line = br.readLine()) != null) {
				uris.add(line);
			}
			br.close();
		}
		return uris;
	}

	public void addLightRule(Rule rule) throws IOException {
		synchronized (lightsLock) {
			String ruleString = "";
			ruleString += rule.getId().toUpperCase();
			ruleString += "\\" + rule.getTime() + "\\";
	
			boolean[] states = (boolean[]) rule.getBody();
			if (states[0])
				ruleString += "KITCHEN/TRUE/";
			else
				ruleString += "KITCHEN/FALSE/";
			if (states[1])
				ruleString += "LIVING ROOM/TRUE/";
			else
				ruleString += "LIVING ROOM/FALSE/";
			if (states[2])
				ruleString += "BEDROOM/TRUE/";
			else
				ruleString += "BEDROOM/FALSE/";
			if (states[3])
				ruleString += "BATHROOM/TRUE";
			else
				ruleString += "BATHROOM/FALSE";
	
			ruleString += "\\" + Boolean.toString(states[4]).toUpperCase();
	
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					lights, true)));
			ps.println(ruleString);
			ps.flush();
			ps.close();
		}
	}

	public void addTempRule(Rule rule) throws IOException {
		deleteTempRule();
		synchronized (tempLock) {
			int temperature = (int) rule.getBody();
			String ruleString = rule.getId() + '\\' + temperature;
	
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					temp, true)));
			ps.println(ruleString);
			ps.flush();
			ps.close();
		}
	}

	public void addIrrigationRule(Rule rule) throws IOException {
		synchronized (irrigationLock) {
			String ruleString = rule.getId();
			ruleString += "\\" + rule.getTime() + "\\";
			boolean state = (boolean) rule.getBody();
			ruleString += Boolean.toString(state).toUpperCase();
	
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					irrigation, true)));
			ps.println(ruleString);
			ps.flush();
			ps.close();
		}
	}

	public List<String> getLightRules() throws IOException {
		List<String> rules = new ArrayList<String>();
		synchronized (lightsLock) {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(lights)));
			String line;
			while ((line = br.readLine()) != null) {
				rules.add(line);
			}
			br.close();
		}
		return rules;
	}

	public List<String> getIrrigationRules() throws IOException {
		List<String> rules = new ArrayList<String>();
		synchronized (irrigationLock) {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(irrigation)));
			String line;
			while ((line = br.readLine()) != null) {
				rules.add(line);
			}
			br.close();
		}
		return rules;
	}

	public List<String> getTempRule() throws IOException {
		List<String> rules = new ArrayList<String>();
		synchronized (tempLock) {
			BufferedReader br = new BufferedReader(new InputStreamReader(
					new FileInputStream(temp)));
			String line;
			while ((line = br.readLine()) != null) {
				rules.add(line);
			}
			br.close();
		}
		return rules;
	}

	public void deleteLightRule(String guid) throws IOException {
		synchronized (lightsLock) {
			List<String> rules = getLightRules();
	
			String delete = null;
			for (String rule : rules) {
				if (rule.contains(guid)) {
					delete = rule;
					break;
				}
			}
			if (delete != null) {
				rules.remove(delete);
			}
	
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					lights, false)));
			for (String rule : rules) {
				ps.println(rule);
			}
			ps.flush();
			ps.close();
		}
	}

	public void deleteIrrigationRule(String guid) throws IOException {
		synchronized (irrigationLock) {
			List<String> rules = getIrrigationRules();
	
			String delete = null;
			for (String rule : rules) {
				if (rule.contains(guid)) {
					delete = rule;
					break;
				}
			}
			if (delete != null) {
				rules.remove(delete);
			}
	
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					irrigation, false)));
			for (String rule : rules) {
				ps.println(rule);
			}
			ps.flush();
			ps.close();
		}
	}

	public void deleteTempRule() throws IOException {
		synchronized (tempLock) {
			PrintWriter ps = new PrintWriter(new BufferedWriter(new FileWriter(
					temp, false)));
			ps.print("");
			ps.flush();
			ps.close();
		}
	}

}